package com.github.jlmd.animatedcircleloadingview.animator;

import com.github.jlmd.animatedcircleloadingview.AnimatedCircleLoadingView;
import com.github.jlmd.animatedcircleloadingview.component.ComponentViewAnimation;
import com.github.jlmd.animatedcircleloadingview.component.InitialCenterCircleView;
import com.github.jlmd.animatedcircleloadingview.component.MainCircleView;
import com.github.jlmd.animatedcircleloadingview.component.PercentIndicatorView;
import com.github.jlmd.animatedcircleloadingview.component.RightCircleView;
import com.github.jlmd.animatedcircleloadingview.component.SideArcsView;
import com.github.jlmd.animatedcircleloadingview.component.TopCircleBorderView;
import com.github.jlmd.animatedcircleloadingview.component.finish.FinishedFailureView;
import com.github.jlmd.animatedcircleloadingview.component.finish.FinishedOkView;
import ohos.agp.components.Component;

/**
 * @author jlmd
 */
public class ViewAnimator implements ComponentViewAnimation.StateListener {

    private InitialCenterCircleView initialCenterCircleView;
    private RightCircleView rightCircleView;
    private SideArcsView sideArcsView;
    private TopCircleBorderView topCircleBorderView;
    private MainCircleView mainCircleView;
    private FinishedOkView finishedOkView;
    private FinishedFailureView finishedFailureView;
    private PercentIndicatorView percentIndicatorView;
    private AnimationState finishedState;
    private boolean resetAnimator;
    private AnimatedCircleLoadingView.AnimationListener animationListener;

    public void setComponentViewAnimations(
            InitialCenterCircleView initialCenterCircleView,
            RightCircleView rightCircleView, SideArcsView sideArcsView,
            TopCircleBorderView topCircleBorderView, MainCircleView mainCircleView,
            FinishedOkView finishedOkCircleView, FinishedFailureView finishedFailureView,
            PercentIndicatorView percentIndicatorView) {
        this.initialCenterCircleView = initialCenterCircleView;
        this.rightCircleView = rightCircleView;
        this.sideArcsView = sideArcsView;
        this.topCircleBorderView = topCircleBorderView;
        this.mainCircleView = mainCircleView;
        this.finishedOkView = finishedOkCircleView;
        this.finishedFailureView = finishedFailureView;
        this.percentIndicatorView = percentIndicatorView;
        initListeners();
    }

    private void initListeners() {
        initialCenterCircleView.setStateListener(this);
        rightCircleView.setStateListener(this);
        sideArcsView.setStateListener(this);
        topCircleBorderView.setStateListener(this);
        mainCircleView.setStateListener(this);
        finishedOkView.setStateListener(this);
        finishedFailureView.setStateListener(this);
    }

    public void startAnimator() {
        finishedState = null;
        initialCenterCircleView.setVisibility(Component.VISIBLE);
        initialCenterCircleView.startTranslateTopAnimation();
        initialCenterCircleView.startScaleAnimation();
        rightCircleView.setVisibility(Component.VISIBLE);
        rightCircleView.startSecondaryCircleAnimation();
    }

    public void resetAnimator() {
        initialCenterCircleView.setVisibility(Component.HIDE);
        rightCircleView.setVisibility(Component.HIDE);
        sideArcsView.setVisibility(Component.HIDE);
        topCircleBorderView.setVisibility(Component.HIDE);
        mainCircleView.setVisibility(Component.HIDE);
        finishedOkView.setVisibility(Component.HIDE);
        finishedFailureView.setVisibility(Component.HIDE);
        resetAnimator = true;
        startAnimator();
    }

    public void finishOk() {
        finishedState = AnimationState.FINISHED_OK;
    }

    public void finishFailure() {
        finishedState = AnimationState.FINISHED_FAILURE;
    }

    public void setAnimationListener(AnimatedCircleLoadingView.AnimationListener animationListener) {
        this.animationListener = animationListener;
    }

    @Override
    public void onStateChanged(AnimationState state) {
        if (resetAnimator) {
            resetAnimator = false;
        } else {
            switch (state) {
                case MAIN_CIRCLE_TRANSLATED_TOP:
                    onMainCircleTranslatedTop();
                    break;
                case MAIN_CIRCLE_SCALED_DISAPPEAR:
                    onMainCircleScaledDisappear();
                    break;
                case MAIN_CIRCLE_FILLED_TOP:
                    onMainCircleFilledTop();
                    break;
                case SIDE_ARCS_RESIZED_TOP:
                    onSideArcsResizedTop();
                    break;
                case MAIN_CIRCLE_DRAWN_TOP:
                    onMainCircleDrawnTop();
                    break;
                case FINISHED_OK:
                case FINISHED_FAILURE:
                    onFinished(state);
                    break;
                case MAIN_CIRCLE_TRANSLATED_CENTER:
                    onMainCircleTranslatedCenter();
                    break;
                case ANIMATION_END:
                    onAnimationEnd();
                    break;
                default:
                    break;
            }
        }
    }

    private void onMainCircleTranslatedTop() {
        topCircleBorderView.setVisibility(Component.HIDE);
        topCircleBorderView.reset();
        mainCircleView.setVisibility(Component.HIDE);
        mainCircleView.reset();
        initialCenterCircleView.setVisibility(Component.VISIBLE);
        initialCenterCircleView.startTranslateBottomAnimation();
        initialCenterCircleView.startScaleDisappear();
    }

    private void onMainCircleScaledDisappear() {
        initialCenterCircleView.setVisibility(Component.HIDE);
        initialCenterCircleView.reset();
        sideArcsView.setVisibility(Component.VISIBLE);
        sideArcsView.startRotateAnimation();
        sideArcsView.startResizeDownAnimation();
    }

    private void onSideArcsResizedTop() {
        sideArcsView.setVisibility(Component.HIDE);
        sideArcsView.reset();
        topCircleBorderView.setVisibility(Component.VISIBLE);
        topCircleBorderView.startDrawCircleAnimation();
    }

    private void onMainCircleDrawnTop() {
        mainCircleView.setVisibility(Component.VISIBLE);
        mainCircleView.startFillCircleAnimation();
    }

    private void onMainCircleFilledTop() {
        if (isAnimationFinished()) {
            topCircleBorderView.setVisibility(Component.HIDE);
            mainCircleView.setVisibility(Component.HIDE);
//            initialCenterCircleView.setVisibility(Component.HIDE);
            onStateChanged(finishedState);
            percentIndicatorView.startAlphaAnimation();
        } else {
            onMainCircleTranslatedTop();
        }
    }

    private boolean isAnimationFinished() {
        return finishedState != null;
    }

    private void onFinished(AnimationState state) {
        topCircleBorderView.setVisibility(Component.HIDE);
        topCircleBorderView.reset();
        mainCircleView.setVisibility(Component.HIDE);
        mainCircleView.reset();
        finishedState = state;
        initialCenterCircleView.setVisibility(Component.VISIBLE);
        initialCenterCircleView.startTranslateCenterAnimation();
    }

    private void onMainCircleTranslatedCenter() {
        initialCenterCircleView.setVisibility(Component.HIDE);
        if (finishedState == AnimationState.FINISHED_OK) {
            finishedOkView.setVisibility(Component.VISIBLE);
            finishedOkView.startScaleAnimation();
        } else {
            finishedFailureView.setVisibility(Component.VISIBLE);
            finishedFailureView.startScaleAnimation();
        }
    }

    private void onAnimationEnd() {
        if (animationListener != null) {
            boolean success = finishedState == AnimationState.FINISHED_OK;
            animationListener.onAnimationEnd(success);
        }
    }
}